package com.nbsaas.boot.app.ext.resource;

import com.nbsaas.boot.app.api.apis.AppMenuApi;
import com.nbsaas.boot.app.api.apis.AppRoleApi;
import com.nbsaas.boot.app.api.apis.AppRoleMenuApi;
import com.nbsaas.boot.app.api.domain.field.AppRoleMenuField;
import com.nbsaas.boot.app.api.domain.request.AppMenuRequest;
import com.nbsaas.boot.app.api.domain.request.AppRoleMenuRequest;
import com.nbsaas.boot.app.api.domain.response.AppMenuResponse;
import com.nbsaas.boot.app.api.domain.response.AppRoleResponse;
import com.nbsaas.boot.app.api.domain.simple.AppMenuSimple;
import com.nbsaas.boot.app.api.domain.simple.AppRoleMenuSimple;
import com.nbsaas.boot.app.data.entity.AppMenu;
import com.nbsaas.boot.app.data.entity.AppRoleMenu;
import com.nbsaas.boot.app.data.mapper.AppMenuMapper;
import com.nbsaas.boot.app.data.repository.AppRoleMenuRepository;
import com.nbsaas.boot.app.ext.apis.AppMenuExtApi;
import com.nbsaas.boot.app.ext.domain.request.MenuDragRequest;
import com.nbsaas.boot.app.ext.domain.request.UpdateRoleMenuRequest;
import com.nbsaas.boot.app.ext.domain.simple.AppMenuExtSimple;
import com.nbsaas.boot.app.ext.helper.TreeHelper;
import com.nbsaas.boot.rest.filter.Filter;
import com.nbsaas.boot.rest.response.ListResponse;
import com.nbsaas.boot.rest.response.ResponseObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class AppMenuExtResource implements AppMenuExtApi {

    @Resource
    private AppMenuApi appMenuApi;

    @Resource
    private AppMenuMapper appMenuMapper;

    @Resource
    private AppRoleMenuApi appRoleMenuApi;

    @Resource
    private AppRoleMenuRepository appRoleMenuRepository;

    @Resource
    private AppRoleApi appRoleApi;

    @Transactional(readOnly = true)
    @Override
    public ListResponse<AppMenuExtSimple> tree(Long appId, Long userId, Long tenant) {
        ListResponse<AppMenuExtSimple> result = new ListResponse<>();
        List<AppMenuSimple> list = appMenuMapper.findByUserMenu(appId, userId, tenant);
        if (list != null) {
            result.setData(TreeHelper.makeTree(list));
        }
        return result;
    }

    @Transactional
    @Override
    public ResponseObject<AppMenuResponse> createExt(AppMenuRequest request) {
        ResponseObject<AppMenuResponse> result = appMenuApi.create(request);
        if (request.getParent() != null) {
            AppMenuRequest parentReq = new AppMenuRequest();
            parentReq.setId(request.getParent());
            parentReq.setCatalog(1);
            appMenuApi.update(parentReq);
        }
        return result;
    }


    @Transactional(readOnly = true)
    @Override
    public ListResponse<AppMenuExtSimple> root(Long appId) {
        ListResponse<AppMenuExtSimple> result = new ListResponse<>();
        List<AppMenuSimple> menus = appMenuApi.listData(Filter.eq("app.id", appId));
        result.setData(TreeHelper.makeTree(menus));
        return result;
    }


    @Override
    public ListResponse<AppMenuExtSimple> findByRole(Long appId, Long role) {
        return null;
    }

    @Transactional
    @Override
    public ListResponse<Long> selectForPermission(Long appId, Long role) {
        ListResponse<Long> result = new ListResponse<>();
        List<AppRoleMenuSimple> roles = appRoleMenuApi.listData(
                Filter.eq("role.id", role)
        );
        if (roles != null) {
            result.setData(roles.stream().map(AppRoleMenuSimple::getMenu).collect(Collectors.toList()));
        }
        return result;
    }

    @Transactional
    @Override
    public List<String> permissions(Long appId, Long role) {
        List<String> result = new ArrayList<>();
        List<AppRoleMenu> roles = appRoleMenuRepository.findByRoleId(role);
        if (roles != null) {
            for (AppRoleMenu menu : roles) {
                AppMenu menuItem = menu.getMenu();
                if (menuItem != null && StringUtils.hasText(menuItem.getPermission())) {
                    result.addAll(Arrays.asList(menuItem.getPermission().split(",")));
                }
            }
        }
        return result;
    }

    @Transactional
    @Override
    public ListResponse<String> selectPermissionByUser(Long appId, Long userId, Long tenant) {
        ListResponse<String> result = new ListResponse<>();
        List<AppMenuSimple> list = appMenuMapper.findByUser(appId, userId, tenant);
        if (list != null) {
            result.setData(new ArrayList<>());
            for (AppMenuSimple menuSimple : list) {
                if (StringUtils.hasText(menuSimple.getPermission())) {
                    result.getData().addAll(Arrays.asList(menuSimple.getPermission().split(",")));
                }
            }
        }
        return result;
    }

    @Transactional
    @Override
    public ResponseObject<?> updateRoleMenus(UpdateRoleMenuRequest request) {
        ResponseObject<?> result = new ResponseObject<>();
        AppRoleResponse role = appRoleApi.oneData(Filter.eq("id", request.getRoleId()));
        if (role == null) {
            result.setCode(501);
            result.setMsg("无效角色id");
            return result;
        }
        appRoleMenuApi.deleteByFilter(Filter.eq(AppRoleMenuField.role, request.getRoleId()));

        for (Long menu : request.getMenus()) {
            AppRoleMenuRequest form = new AppRoleMenuRequest();
            form.setRole(request.getRoleId());
            form.setMenu(menu);
            form.setApp(role.getApp());
            appRoleMenuApi.createData(form);
        }

        return result;
    }

    @Override
    public ResponseObject<?> drag(MenuDragRequest request) {
        return null;
    }
}
